/*************************************************************************
Purpose:  This program edits an input (AND ORBIT)file in various ways. For
          instance, setting edit_choice to 1 removes input pts that are
          deemed "bad" from the input and orbit file. The bad points are
          marked using a long vector called bad_input_times
**************************************************************************    
Input:    Reads a file called input.
**************************************************************************    
Output:   Writes a file called output.
**************************************************************************      
Copyright 2010 Bryan Killett

This file is part of GAIA.

GAIA is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

GAIA is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GAIA. If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/
//Header file "definitions.hpp" declares many functions, constants, datatypes.
//In order to use the functions declared in definitions.hpp, must link
//with object code that includes functions.cpp.
#include "definitions.hpp"

int main(){
  // 1 - Remove selected input points based on values in bad_input_times.
  // 2 - Remove selected lines in the input file based on their line number
  //10 - Makes new input file with accels = input accels minus input2 accels.
  //11 - Makes new input file with accels = input accels  plus input2 accels.
  //20 - Only keep ascending input points.
  //21 - Only keep descending input points.
  //30 - Only keep 1 out of every "decimate" input points.
  //40 - Only keep input points with a lat < "param1"
  //41 - Only keep input points with a lat > "param1"
  //50 - Only keep points after start_time and before end_time.
  //60 - Convert from input_and_orbit to BRIEF accels.
  //61 - Convert from BRIEF accels to input_and_orbit using input2 as (MATCHING!) orbit.
  //62 - BROKEN Convert from SUNGBYUN to input_and_orbit using input2 as (MATCHING!) orbit.
  //63 - Convert FLEXIBLY from SUNGBYUN to input_and_orbit using input2 as orbit file.
  //100- Replace accelerations with random noise of equal mean and variance.
  //110- Replace accelerations with a sinusoid of period param1 (s) and amp param2 (AU).
  int edit_choice = 30;
  long decimate=5;
  double param1=50.0, param2=4.6e-9;
  
  string input(gaiafolder()),input2(gaiafolder()), output(gaiafolder());
  //input.append("data/GRACE/stack_7_yrs_20s_smoothing.txt");
  //input.append("data/GRACE/deg150/stack_deg150_2008_20s_smoothing_global.txt");
  //input.append("data/GRACE/stack_deg90_2008_20s_smoothing_50N.txt");
  //input.append("data/GRACE/stack_and_orbit_7yrs_fixed_orbit.txt");
  //input.append("data/GRACE/stack_and_orbit_deg90_minus_deg150_2008_20s_smoothing.txt");
  //input.append("data/GRACE/stack_and_orbit_sim_type_69.txt");
  //input.append("data/GRACE/stack_and_orbit_sim_type_119_supp0.txt");
  //input.append("data/GRACE/stack_and_orbit_gaia_global_region2.txt");
  input.append("data/GRACE/stack_and_orbit_land_and_ocean_edited.txt");
  //input.append("data/GRACE/stack_and_orbit_noise_from_land_ocean.txt");
  //input.append("data/GRACE/CRN-RAW");
  //input.append("data/GRACE/stack_and_orbit_deg90_2008_20s_smoothing_498Nmaybe.txt");
  //output.append("data/GRACE/sim_accels.txt");
  //output.append("data/GRACE/stack_and_orbit_gaia_minus_sima.txt");
  //output.append("data/GRACE/stack_and_orbit_noise_plus_sine_50s.txt");
  output.append("data/GRACE/stack_and_orbit_land_and_ocean_edited_1_of_5.txt");

  //Used in type 10,61.
  //input2.append("data/GRACE/stack_and_orbit_sim_type_56.txt");
  //input2.append("data/GRACE/stack_and_orbit_deg150_2008_20s_smoothing_50N.txt");
  //input2.append("data/GRACE/stack_and_orbit_7yrs_fixed_orbit.txt");
  //input2.append("data/GRACE/stack_and_orbit_sim_type_69.txt");
  //input2.append("data/GRACE/stack_and_orbit_sim_type_122_plus_125.txt");
  //input2.append("data/GRACE/stack_and_orbit_sim_type_107_supp0.txt");
  //input2.append("data/GRACE/stack_deg150_2008_20s_smoothing_50N.txt");
  input2.append("data/GRACE/stack_and_orbit_sine_50s_from_land_ocean.txt");

  time_conversion_s start_time, end_time;
  
  start_time.calendar_time.resize(6,0);//Usually just specify date, not time.
  start_time.calendar_time.front() = 2002;//year
  start_time.calendar_time.at(1) = 1;//month - 0 is meaningless!
  start_time.calendar_time.at(2) = 1;//day - 0 is meaningless!
  
  end_time.calendar_time.resize(6,0);//Usually just specify date, not time.
  end_time.calendar_time.front() = 2003;//year
  end_time.calendar_time.at(1) = 1;//month - 0 is meaningless!
  end_time.calendar_time.at(2) = 1;//day - 0 is meaningless!
  
  double start_seconds, end_seconds;
  long long input_counter=0,input_counter2=0,output_counter=0,deleted_counter=0;
  char s[max_length];
  char s2[max_length];
  double onelat,onelon,oneaccel,onexA,onexB,oneyA,oneyB,onezA,onezB;
  long long onetime;
  int oneascending;
  double onelat2,onelon2,oneaccel2,onexA2,onexB2,oneyA2,oneyB2,onezA2,onezB2;
  long long onetime2;
  int oneascending2;
  FILE *in_fp,*in_fp2;
  FILE *out_fp;
  double newaccel;
  vector <long> bad_input_times,bad_input_lines;
  char* f_return;//Used to stop fgets return value warning.

  //Older input files do not contain orbit data.  If loading one of these
  //files (identifiable because the filename doesn't contain "_and_orbit",
  //set this variable to 1.  Otherwise it's 0.
  int no_orbit_data;
  if(((int)input.find("_and_orbit"))!=(int)string::npos) no_orbit_data = 0;
  else no_orbit_data = 1;
  
  //Open input file for loading.
  in_fp = fopen(input.c_str(),"r");

  //Warn if input file doesn't open correctly.
  if (!in_fp) cout << "The input file, " << input
                   << ", failed to open."<<endl;
  else cout << "Loading input data from file " 
            << input << "..."<<endl;

  //Open output file for writing.
  out_fp = fopen(output.c_str(),"w");

  //Warn if output file doesn't open correctly.
  if (!in_fp) cout << "The output file, " << output
                   << ", failed to open."<<endl;
  else cout << "Writing output data to file " 
            << output << "..."<<endl;

  //Load the first header line separately because it contains no data.
  f_return=fgets(s,max_length,in_fp);

  switch(edit_choice){
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 1:{
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      bad_input_times.push_back(138413721);
      bad_input_times.push_back(138414246);
      bad_input_times.push_back(150558770);

      //Load each line of data as a string, parse into numeric values,
      //then figure out if this is a bad pt or a good pt.  If good,
      //write it to the output file.  If bad, ignore it.
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;    
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        //If this onetime isn't in the bad_input_times vector, copy it.
        if(count(bad_input_times.begin(),bad_input_times.end(),onetime) == 0){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
          cout<<"Deleting line with values: "<<endl<<s<<endl<<endl;
        }  
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file has "<<input_counter<<" input points."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input points."<<endl;
      cout<<"Output file has "<<output_counter<<" input points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 2:{
    
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      output_counter++; input_counter++;//The header line was already read, and written.
      //Don't try to choose line 1! That was already read and written.
      bad_input_lines.push_back(2);

      //Load each line and write it to the output file if it isn't
      // a "bad_input_line".
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;//This runs first so the first line is "1".
        //If this line # isn't in the bad_input_lines vector, copy it.
        if(count(bad_input_lines.begin(),bad_input_lines.end(),input_counter) == 0){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
          cout<<"Deleting line: "<<endl<<s<<endl<<endl;
        }  
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"CHANGE THESE STATEMENTS!"<<endl;
      cout<<"Input file has "<<input_counter<<" lines."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input lines."<<endl;
      cout<<"Output file has "<<output_counter<<" lines."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 10:
    case 11:{

      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      //Open input file for loading.
      in_fp2 = fopen(input2.c_str(),"r");

      //Warn if input file doesn't open correctly.
      if (!in_fp2) cout << "The 2nd input file, " << input2
                       << ", failed to open."<<endl;
      else cout << "Loading input data from 2nd file " 
                << input2 << "..."<<endl;

      //Load the first header line separately because it contains no data.
      f_return=fgets(s2,max_length,in_fp2);

      //Load each line of data as a string, parse into numeric values,
      //then calc diff accel to write to output file.
      while(fgets(s,max_length,in_fp)!=NULL and fgets(s2,max_length,in_fp2)!=NULL){
        input_counter++; input_counter2++;
        parse_input_line(s, onetime, onelat, onelon, oneaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB, no_orbit_data);
        parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, no_orbit_data);
        
        //Make sure the 2 input points are at same time.
        while(onetime != onetime2){
          if(onetime < onetime2){
            //Time1 is too early, so read from file1 until it matches or exceeds time2.
            f_return=fgets(s,max_length,in_fp); input_counter++;
            parse_input_line(s, onetime, onelat, onelon, oneaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB, no_orbit_data);
          }
          else{
            //Time2 is too early, so read from file2 until it matches or exceeds time1.
            f_return=fgets(s2,max_length,in_fp2); input_counter2++;
            parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, no_orbit_data);
          }
        }
        
        //Make sure the 2 input points are at same place.
        if(fabs(onelat - onelat2) > high_tolerance) cout<<"!!!WARNING TYPE 2 - onelat = "<<onelat<<" while onelat2 = "<<onelat2<<endl;
        if(fabs(onelon - onelon2) > high_tolerance) cout<<"!!!WARNING TYPE 3 - onelon = "<<onelon<<" while onelon2 = "<<onelon2<<endl;
       
        if(edit_choice == 10) newaccel = oneaccel - oneaccel2;
        else if(edit_choice == 11) newaccel = oneaccel + oneaccel2;

        if(no_orbit_data == 0){
          fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat, onelon, newaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB);
        }
        else{
          fprintf(out_fp,ACCEL_WRITE_FORMAT, onetime, onelat, onelon, newaccel, oneascending);
        }
        output_counter++;
      }
      fclose(in_fp); fclose(out_fp); fclose(in_fp2);
   
      cout<<"Input file 1 has "<<input_counter<<" points."<<endl;
      cout<<"Input file 2 has "<<input_counter2<<" points."<<endl;
      cout<<"Output file has "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 20://Only keep ascending pts.
    case 21:{//Only keep descending pts.
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      //Load each line of data as a string, parse into numeric values, then
      //remove descending (case 20) or ascending (case 21).
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;    
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        if((oneascending==1 and edit_choice==4) or (oneascending==0 and edit_choice==5)){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
        }
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file has "<<input_counter<<" input points."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input points."<<endl;
      cout<<"Output file has "<<output_counter<<" input points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 30:{//Only keep one point out of every "decimate" pts.
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      //Load each line of data as a string, parse into numeric values, then
      //remove most pts.
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;    
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        //Only keep every "decimate" input pt.
        if(input_counter % decimate == 0){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
        }  
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file has "<<input_counter<<" input points."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input points."<<endl;
      cout<<"Output file has "<<output_counter<<" input points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 40: //Only keep input points with lat < "param1"
    case 41:{//Only keep input points with lat > "param1"
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;
        if(no_orbit_data == 0)
          sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        else
          sscanf(s,ACCEL_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending);
        if((onelat < param1 and edit_choice == 40) or (onelat > param1 and edit_choice == 41)){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
        }
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file has "<<input_counter<<" input points."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input points."<<endl;
      cout<<"Output file has "<<output_counter<<" input points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 50:{//Only keep points after start_time and before end_time.
      //Copy header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);
      
      cal2utc(start_time);//Convert calendar time to UTC seconds.
      start_seconds = start_time.utc_seconds;
      cal2utc(end_time);//Convert calendar time to UTC seconds.
      end_seconds = end_time.utc_seconds;
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;    
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        if(onetime > start_seconds and onetime < end_seconds){
          output_counter++;
          fprintf(out_fp,"%s",s);
        }
        //Otherwise ignore it.
        else{
          deleted_counter++;
        }
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file has "<<input_counter<<" input points."<<endl;
      cout<<"Deleted "<<deleted_counter<<" input points."<<endl;
      cout<<"Output file has "<<output_counter<<" input points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 60:{//Convert from input_and_orbit to BRIEF input accels.
      //Write accel header line to output file.
      fprintf(out_fp,ACCEL_HEADER);
      
      //Load each line of data as a string, parse into numeric values,
      //then calc diff accel to write to output file.
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;
        parse_input_line(s, onetime, onelat, onelon, oneaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB, no_orbit_data);
        fprintf(out_fp,"%11lld%10.1f%10.1f%13.5e\n", onetime, onelat, onelon, oneaccel);
        output_counter++;
      }
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file 1 has "<<input_counter<<" points."<<endl;
      cout<<"Output file has "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 61:{//Convert from BRIEF input accels to input_and_orbit using input2 as (MATCHING!) orbit.
      //Open orbit file for loading.
      in_fp2 = fopen(input2.c_str(),"r");

      //Warn if input file doesn't open correctly.
      if (!in_fp2) cout << "The orbit file, " << input2
                       << ", failed to open."<<endl;
      else cout << "Loading orbit data from 2nd file " 
                << input2 << "..."<<endl;

      //Load the first header line separately because it contains no data.
      f_return=fgets(s2,max_length,in_fp2);

      //Copy orbit header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s2);
      
      //Load each line of data as a string, parse into numeric values,
      //then calc diff accel to write to output file.
      while(fgets(s,max_length,in_fp)!=NULL and fgets(s2,max_length,in_fp2)!=NULL){
        input_counter++; input_counter2++;
        parse_input_line(s, onetime, onelat, onelon, oneaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB, 1);
        parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, 0);
        
        //Make sure the 2 input points are at same time.
        if(onetime != onetime2) cout<<"!!!WARNING!!! onetime = "<<onetime<<" but onetime2 = "<<onetime2<<endl;
        
        //Make sure the 2 input points are at "same" place, given brief's 0.1 precision...
        if(fabs(onelat - onelat2) > 0.2) cout<<"!!!WARNING TYPE 2 - onelat = "<<onelat<<" while onelat2 = "<<onelat2<<endl;
        if(fabs(onelon - onelon2) > 0.2) cout<<"!!!WARNING TYPE 3 - onelon = "<<onelon<<" while onelon2 = "<<onelon2<<endl;
        
        fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat2, onelon2, oneaccel, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2);
        output_counter++;
      }
      fclose(in_fp); fclose(out_fp); fclose(in_fp2);
   
      cout<<"Input file 1 has "<<input_counter<<" points."<<endl;
      cout<<"Input orbit file 2 has "<<input_counter2<<" points."<<endl;
      cout<<"Output orbit file has  "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    //BROKEN
    case 62:{//Convert from SUNGBYUN to input_and_orbit using input2 as (MATCHING!) orbit.
      //Open orbit file for loading.
      in_fp2 = fopen(input2.c_str(),"r");

      //Warn if input file doesn't open correctly.
      if (!in_fp2) cout << "The orbit file, " << input2
                       << ", failed to open."<<endl;
      else cout << "Loading orbit data from 2nd file " 
                << input2 << "..."<<endl;

      //Load the first header line separately because it contains no data.
      f_return=fgets(s2,max_length,in_fp2);

      //Copy orbit header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s2);
      
      //Load each line of data as a string, parse into numeric values,
      //then calc diff accel to write to output file.
      while(fgets(s,max_length,in_fp)!=NULL and fgets(s2,max_length,in_fp2)!=NULL){
        input_counter++; input_counter2++;
        sscanf(s,"%lld %lf %lf %lf %lf %lf", &onetime, &onelat, &onelon, &oneaccel, &onexA, &onexB);
        parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, 0);
        
        //Make sure the 2 input points are at same time.
        if(onetime != onetime2) cout<<"!!!WARNING!!! onetime = "<<onetime<<" but onetime2 = "<<onetime2<<endl;
        
        //Make sure the 2 input points are at "same" place, given brief's 0.1 precision...
        if(fabs(onelat - onelat2) > 0.2) cout<<"!!!WARNING TYPE 2 - onelat = "<<onelat<<" while onelat2 = "<<onelat2<<endl;
        if(fabs(onelon - onelon2) > 0.2) cout<<"!!!WARNING TYPE 3 - onelon = "<<onelon<<" while onelon2 = "<<onelon2<<endl;
        
        fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat2, onelon2, oneaccel, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2);
        output_counter++;
      }
      fclose(in_fp); fclose(out_fp); fclose(in_fp2);
   
      cout<<"Input file 1 has "<<input_counter<<" points."<<endl;
      cout<<"Input orbit file 2 has "<<input_counter2<<" points."<<endl;
      cout<<"Output orbit file has  "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 63:{//Convert FLEXIBLY from SUNGBYUN to input_and_orbit using input2 as orbit file.
      no_orbit_data = 0;//Over-ride usual setting.

      //Open input file for loading.
      in_fp2 = fopen(input2.c_str(),"r");

      //Warn if input file doesn't open correctly.
      if (!in_fp2) cout << "The 2nd input file, " << input2
                       << ", failed to open."<<endl;
      else cout << "Loading input data from 2nd file " 
                << input2 << "..."<<endl;

      //Load the first header line separately because it contains no data.
      f_return=fgets(s2,max_length,in_fp2);

      //Copy orbit header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s2);
      
      //Load each line of data as a string, parse into numeric values,
      //then calc diff accel to write to output file.
      while(fgets(s,max_length,in_fp)!=NULL and fgets(s2,max_length,in_fp2)!=NULL){
        input_counter++; input_counter2++;
        sscanf(s,"%lld %lf %lf %lf %lf %lf", &onetime, &onelat, &onelon, &oneaccel, &onexA, &onexB);
        parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, no_orbit_data);
        
        //Make sure the 2 input points are at same time.
        while(onetime != onetime2){
          if(onetime < onetime2){
            //Time1 is too early, so read from file1 until it matches or exceeds time2.
            f_return=fgets(s,max_length,in_fp); input_counter++;
            sscanf(s,"%lld %lf %lf %lf %lf %lf", &onetime, &onelat, &onelon, &oneaccel, &onexA, &onexB);
          }
          else{
            //Time2 is too early, so read from file2 until it matches or exceeds time1.
            f_return=fgets(s2,max_length,in_fp2); input_counter2++;
            parse_input_line(s2, onetime2, onelat2, onelon2, oneaccel2, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2, no_orbit_data);
          }
        }
        
        //Make sure the 2 input points are at same time.
        if(onetime != onetime2) cout<<"!!!WARNING!!! onetime = "<<onetime<<" but onetime2 = "<<onetime2<<endl;
        
        //Make sure the 2 input points are at "same" place, given brief's 0.1 precision...
        if(fabs(onelat - onelat2) > 0.2) cout<<"!!!WARNING TYPE 2 - onelat = "<<onelat<<" while onelat2 = "<<onelat2<<endl;
        if(fabs(onelon - onelon2) > 0.2) cout<<"!!!WARNING TYPE 3 - onelon = "<<onelon<<" while onelon2 = "<<onelon2<<endl;
        
        fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat2, onelon2, oneaccel, oneascending2, onexA2, onexB2, oneyA2, oneyB2, onezA2, onezB2);
        output_counter++;
      }
      fclose(in_fp); fclose(out_fp); fclose(in_fp2);
   
      cout<<"Input file 1 has "<<input_counter<<" points."<<endl;
      cout<<"Input file 2 has "<<input_counter2<<" points."<<endl;
      cout<<"Output file has "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 100:{//Replace accelerations with random noise of equal mean and variance.
      double mean=0.0,variance=0.0;
      no_orbit_data = 0;//Over-ride usual setting.

      cout<<"Reading input file to calculate mean, variance."<<endl;

      //Copy orbit header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);

      //Load each line of data as a string, parse into numeric values,
      //then figure out if this is a bad pt or a good pt.  If good,
      //write it to the output file.  If bad, ignore it.
      while(fgets(s,max_length,in_fp)!=NULL){
        input_counter++;
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        mean += oneaccel;
        variance += pow(oneaccel,2);
      }
      fclose(in_fp);
      mean /= (double)input_counter;
      variance /= (double)input_counter;
      cout<<"Mean    : "<<scientific<<setprecision(10)<<mean<<endl;
      cout<<"Variance: "<<scientific<<setprecision(10)<<variance<<endl;
      cout<<"Std Dev : "<<scientific<<setprecision(10)<<sqrt(variance)<<endl;

      //Reopen input file.
      in_fp = fopen(input.c_str(),"r");

      //Warn if input file doesn't open correctly.
      if (!in_fp) cout << "The input file, " << input
                       << ", failed to open."<<endl;
      else cout<<"Finished. Writing new file with noise of same mean, variance."<<endl;

      //Load the first header line separately because it contains no data.
      f_return=fgets(s,max_length,in_fp);

      //Requires GSL libraries.
      #ifdef GSL_HERE
        double sigma = sqrt(variance);
        const gsl_rng_type * R;
        gsl_rng * r;
        
        gsl_rng_env_setup();
        R = gsl_rng_default;
        r = gsl_rng_alloc(R);
        gsl_rng_set(r,time(0));

        while(fgets(s,max_length,in_fp)!=NULL){
          sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
          output_counter++;
          newaccel = mean + gsl_ran_gaussian(r,sigma);
          fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat, onelon, newaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB);
        }
          
      #else 
        cout<<"Noise generation requires GSL. Search definitions.cpp for GSL_HERE."<<endl;
      #endif
      
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file  has "<<input_counter<<" points."<<endl;
      cout<<"Output file has "<<output_counter<<" points."<<endl;

      break;
    }
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    case 110:{//Replace accels with a sinusoid of period param1 and amp param2.
      no_orbit_data = 0;//Over-ride usual setting.

      //Copy orbit header line to output file.  No need for \n, it's already there.
      fprintf(out_fp,"%s",s);

      while(fgets(s,max_length,in_fp)!=NULL){
        sscanf(s,ORBIT_READ_FORMAT, &onetime, &onelat, &onelon, &oneaccel, &oneascending, &onexA, &onexB, &oneyA, &oneyB, &onezA, &onezB);
        input_counter++; output_counter++;
        newaccel = param2*cos(twoPi/param1*onetime);
        fprintf(out_fp,ORBIT_WRITE_FORMAT, onetime, onelat, onelon, newaccel, oneascending, onexA, onexB, oneyA, oneyB, onezA, onezB);
      }
       
      fclose(in_fp); fclose(out_fp);
   
      cout<<"Input file  has "<<input_counter<<" points."<<endl;
      cout<<"Output file has "<<output_counter<<" points."<<endl;

      break;
    }
  }
  return 0;
}
